package com.zg.autoflow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.utils.MT;
import com.xn.fastxls.InfoException;
import com.zg.autoflow.dao.mapper.WorkflowInstanceMapper;
import com.zg.autoflow.req.AutoflowExtStepConfigReq;
import com.zg.autoflow.req.WorkflowInstanceReq;
import com.zg.autoflow.req.WorkflowStepDataReq;
import com.zg.autoflow.req.processListReq;
import com.zg.autoflow.service.AutoflowExtStepConfigService;
import com.zg.autoflow.service.SettleWorkflowInstanceService;
import com.zg.autoflow.vo.*;
import com.zg.common.core.R;
import com.zg.common.core.User;
import com.zg.common.core.constant.FlowContants;
import com.zg.common.core.dao.autoflow.dao.*;
import com.zg.common.core.dao.autoflow.entity.*;
import com.zg.common.core.util.GUIDUtils;
import com.zg.common.dds.DbTypeUtil;
import com.zg.common.web.Req;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
* @author zg
*/
@Service
@RequiredArgsConstructor
public class SettleWorkflowInstanceServiceImpl implements SettleWorkflowInstanceService {

    private final WorkflowInstanceMapper workflowInstanceMapper;
    private final SettleWorkflowInstanceDao settleWorkflowInstanceDao;
    private final SettleWorkflowStepInstanceDao settleWorkflowStepInstanceDao;
    private final SettleWorkflowInstanceLinkDao settleWorkflowInstanceLinkDao;
    private final SettleBizformDao settleBizformDao;
    private final SettleWorkflowDelegaterDao settleWorkflowDelegaterDao;
    private final AutoflowExtStepConfigService autoflowExtStepConfigService;
    private final DbTypeUtil dbTypeUtil;


    @Override
    public synchronized String createInsCode() {
        return GUIDUtils.getUUID32WithPrefix(FlowContants.FLOWINS_PRE);
    }

    @Override
    public List<SettleBizformPdfVo> getMainPdfList(WorkflowStepDataReq req) {
        SettleWorkflowStepInstance workflowStepInstance = settleWorkflowStepInstanceDao.getOne(new LambdaQueryWrapper<SettleWorkflowStepInstance>().eq(SettleWorkflowStepInstance::getStepInstCode, req.getStepInstCode()));
        Map<String, Object> isStepInstBySCGS = workflowInstanceMapper.isStepInstBySCGS(workflowStepInstance.getInstCode(), workflowStepInstance.getStepInstCode());
        List<SettleBizformPdfVo> pdfFileList = null;
        if (isStepInstBySCGS != null && "根据合同选市场".equals(isStepInstBySCGS.get("SELECT_HANDLER_MODE"))) {
            pdfFileList = workflowInstanceMapper.pdfFileSCGSList(req.getInstCode(),workflowStepInstance.getStepCode(),"true");
        }else {
            pdfFileList = workflowInstanceMapper.getPdfFileListByInstCode(workflowStepInstance.getInstCode(),workflowStepInstance.getStepCode(), "true");
        }
        if (pdfFileList.isEmpty()) {
            return new ArrayList<>();
        }
        Set<String> keySet = new HashSet<>();
        List<SettleBizformPdfVo> newPDFList = new ArrayList<>();
        for (SettleBizformPdfVo vo : pdfFileList) {
            String form_model_code = vo.getFormId()+"";
            if (keySet.contains(form_model_code)) {
                continue;
            }
            keySet.add(form_model_code);
            newPDFList.add(0, vo);
        }
        return newPDFList;
    }

    @Override
    public List<SettleBizformPdfVo> getFrontFlowList(WorkflowStepDataReq req) {
        //获取实例code
        String instCode = req.getInstCode();
        String stepInstCode = req.getStepInstCode();
        Long userId = Req.getCurrUser().getId();
        //流程实例
        SettleWorkflowStepInstance stepInstance = settleWorkflowStepInstanceDao.getOne(new LambdaQueryWrapper<SettleWorkflowStepInstance>().eq(SettleWorkflowStepInstance::getStepInstCode,stepInstCode));
        if (stepInstance == null) {
            throw new InfoException("无此流程");
        }
        AutoflowExtStepConfigReq autoflowExtStepConfigReq = new AutoflowExtStepConfigReq();
        autoflowExtStepConfigReq.setFlowCode(stepInstance.getFlowCode());
        autoflowExtStepConfigReq.setStepNo(stepInstance.getStepCode());
        AutoflowExtStepConfigFindVo stepForm = autoflowExtStepConfigService.findStepForm(autoflowExtStepConfigReq);
        List<SettleBizformPdfVo> settleBizformPdfVos = new ArrayList<>();
        List<SettleWorkflowInstanceLink> list = settleWorkflowInstanceLinkDao.list(new LambdaQueryWrapper<SettleWorkflowInstanceLink>()
                .eq(SettleWorkflowInstanceLink::getToInstCode, instCode)
                .eq(SettleWorkflowInstanceLink::getDeleteState, "0"));
        if (CollectionUtil.isNotEmpty(list)){
            List<String> preInstCode = list.stream().map(SettleWorkflowInstanceLink::getToInstCode).collect(Collectors.toList());
            if (ObjectUtil.isNotEmpty(stepForm)&&CollectionUtil.isNotEmpty(stepForm.getPrevsList())){
                List<String> flowCodeFormId = stepForm.getPrevsList().stream().map(line -> {
                    return line.getPrevFlowCode() + line.getPrevFlowFormCode();
                }).collect(Collectors.toList());
                String dbType =null;
                if (dbTypeUtil.isMysql()){
                    dbType="0";
                }else if (dbTypeUtil.isOracle()){
                    dbType="1";
                }
                settleBizformPdfVos=workflowInstanceMapper.getFrontFlowList(preInstCode,flowCodeFormId,dbType);
            }else {
                List<SettleBizform> settleBizforms = settleBizformDao.list(new LambdaQueryWrapper<SettleBizform>().in(SettleBizform::getInstCode, preInstCode).isNotNull(SettleBizform::getPdfFilePath).orderByAsc(SettleBizform::getCreateDate));
                settleBizformPdfVos = BeanUtil.copyToList(settleBizforms, SettleBizformPdfVo.class);
            }
        }
        return settleBizformPdfVos;
    }

    @Override
    public R getProcessList(processListReq paramMap) {
        Long userId =Req.getCurrUser().getId();
        Date date = new Date();
        LambdaQueryWrapper<SettleWorkflowDelegater> wrapper = new LambdaQueryWrapper<SettleWorkflowDelegater>().eq(SettleWorkflowDelegater::getOperator, userId)
                .ge(SettleWorkflowDelegater::getEffectiveBeginDate, date).le(SettleWorkflowDelegater::getEffectiveEndDate, date);
        List<SettleWorkflowDelegater> list = settleWorkflowDelegaterDao.list(wrapper);
        if (CollectionUtil.isNotEmpty(list)){
            SettleWorkflowDelegater settleWorkflowDelegater = list.get(0);
            String delegaterUserId = settleWorkflowDelegater.getDelegater();
            paramMap.setUserId(delegaterUserId);
           IPage<SettleWorkflowInstanceVo> currentUserProcessList = workflowInstanceMapper.getCurrentUserProcessList(new Page(paramMap.getPage(), paramMap.getPageSize()), paramMap);
            return R.success(currentUserProcessList);
        }else {
            return R.success();
        }
    }



    @Override
    public IPage<WorkflowInstanceVo> getTodoWorkflowInstancePage(Page page, WorkflowInstanceReq workflowInstanceReq) {
        User currUser = Req.getCurrUser();
        if (currUser == null) {
            throw new RuntimeException("用户未登录");
        }
       List<String> userIds = new ArrayList<>();
        String dbType =null;
        if ( dbTypeUtil.isMysql()){
            dbType="0";
        }else if (dbTypeUtil.isOracle()){
            dbType="1";
        }
        workflowInstanceReq.setDbType(dbType);
        if("0".equals(workflowInstanceReq.getFlowInstState())){
            if ("0".equals(workflowInstanceReq.getType())){
                Date date = new Date();
                LambdaQueryWrapper<SettleWorkflowDelegater> wrapper = new LambdaQueryWrapper<SettleWorkflowDelegater>().eq(SettleWorkflowDelegater::getDelegater, currUser.getId())
                        .ge(SettleWorkflowDelegater::getEffectiveBeginDate, date).le(SettleWorkflowDelegater::getEffectiveEndDate, date);
                List<SettleWorkflowDelegater> list = settleWorkflowDelegaterDao.list(wrapper);
                userIds = list.stream().map(SettleWorkflowDelegater::getOperator).collect(Collectors.toList());
            }else {
                // 获取用户ID
                String userId = currUser.getId().toString();
                userIds.add(userId);
            }
            if (CollectionUtil.isNotEmpty(userIds)){
                workflowInstanceReq.setUserId(userIds);
                return workflowInstanceMapper.getTodoWorkflowInstancePage(page, workflowInstanceReq);
            }
        }else {
            userIds.add(currUser.getId().toString());
            workflowInstanceReq.setUserId(userIds);
            return workflowInstanceMapper.getTodoWorkflowInstanceEndPage(page, workflowInstanceReq);
        }
        return new Page<WorkflowInstanceVo>();
    }
}
